﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Lextm.SharpSnmpLib;
using Lextm.SharpSnmpLib.Messaging;
using System.Net;
using SManage.LibExtension;
using SManage.Model;
using System.Threading.Tasks;
using System.Threading;

namespace SManage.TraceEngine
{
    public class SyncEngine
    {
        private SyncTaskPool stp;
        private IList<System.Timers.Timer> syncTimers = new List<System.Timers.Timer>();
        private Boolean _running;
        private SManageEntities sme;

        public Boolean Running {
            get { return _running; }
        }

        public SyncEngine() {
            stp = SyncTaskPool.Default;
            stp.SyncItemChanged += ReadToSync;
            sme = new SManageEntities();
        }

        private void Init() {
            syncTimers.Clear();
            foreach (SyncItem si in stp) {
                syncTimers.Add(ParseTimer(si));
            }            
        }

        private System.Timers.Timer ParseTimer(SyncItem si) {

            var timer = new System.Timers.Timer(si.Interval.TotalMilliseconds);
            timer.Elapsed += (o, e) => {
                Console.WriteLine("ProcessItem.");
                ProcessItem(si);
            };
            return timer;
        }

        private void ProcessItem(SyncItem item) {
            var device = Mapping(item);
            if (device == null) {
                return;
            }

            var targetIp = item.EndPoint.Address.ToString();
            var target = from de in sme.Devices
                         from ip in de.Mib2_ip.Mib2_ip_ipAddrEntry
                         where ip.ipAdEntAddr.Trim() == targetIp
                         select de;

            if (target.Count() < 1) {
                sme.AddToDevices(device);
                Console.WriteLine("Add new One.");
            } else {
                var firstTarget = target.First();
                firstTarget = device;
                Console.WriteLine("Update new One.");
            }
            Console.WriteLine("Done!");
            sme.SaveChanges();
            item.Update();
        }

        private Device Mapping(SyncItem item) {
            DeviceInfo di = new DeviceInfo(item);
            var device = di.Process();
            return device;
        }

        private void ReadToSync(Object sender, SyncItemChangedEventArgs e) {
            var t = ParseTimer(e.Item);
            syncTimers.Add(t);
            if(_running) {
                t.Enabled = true;
            }
        }

        public void Start() {
            Init();
            foreach (var t in syncTimers) {
                t.Enabled = true;
            }
            _running = true;
        }

        public void Stop() {
            foreach (var t in syncTimers) {
                t.Dispose();
            }
            _running = false;
        }

        // Not implemented.
        public void Pause() {
            throw new NotImplementedException();
        }
    }
}
